package com.reading.common.utils;

import org.apache.commons.lang.time.DateFormatUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 时间获取和转换工具类
 */
public class DateUtil {

    private static final int[] dayArray = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    private static final SimpleDateFormat sdf = new SimpleDateFormat();
    private static final String pattern = "yyyy-MM-dd";
    public static final String YYYY = "yyyy";
    public static final String YYYY_MM = "yyyy-MM";
    public static final String YYYYMM = "yyyyMM";
    public static final String YYYYMMdd = "yyyyMMdd";
    public static final String YYYYMMddHHmm = "yyyyMMddHHmm";

    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss,SSS";

    private static SimpleDateFormat formatter = new SimpleDateFormat(YYYY_MM_DD);
    private static SimpleDateFormat formatter2 = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
    private static DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(YYYY_MM_DD);

    /**
     * 标准日期格式MM/dd/yyyy
     */
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy");

    /**
     * 标准时间格式MM/dd/yyyy HH:mm
     */
    private static final SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat("MM/dd/yyyy HH:mm");

    /**
     * ORA标准日期格式yyyyMMdd
     */
    public static final SimpleDateFormat ORA_DATE_FORMAT = new SimpleDateFormat(YYYYMMdd);
    /**
     * yyyyMM
     */
    public static final SimpleDateFormat ORA_DATE_MONTH_FORMAT = new SimpleDateFormat(YYYYMM);

    /**
     * ORA标准时间格式yyyyMMddHHmm
     */
    private static final SimpleDateFormat ORA_DATE_TIME_FORMAT = new SimpleDateFormat(YYYYMMddHHmm);

    public static Calendar getCalendar() {
        return GregorianCalendar.getInstance();
    }

    /**
     * 得到格式为pattern的时间字符串
     *
     * @return String 得到格式为pattern的时间字符串
     */
    public static String getDateFormat(String pattern) {
        Calendar cal = Calendar.getInstance();
        return getDateFormat(cal, pattern);
    }

    /**
     * 根据日期(Calendar)和日期格式返回对应的字符串
     *
     * @param cal Calendar参数
     * @param pattern 传入的日期格式(例如：yyyy-MM-dd HH:mm:ss)
     * @return String 日期字符串
     */
    public static String getDateFormat(Calendar cal, String pattern) {
        return getDateFormat(cal.getTime(), pattern);
    }

    /**
     * 根据日期(Date)和日期格式返回对应的字符串
     *
     * @param date Date类型日期
     * @param pattern 传入的日期格式(例如：yyyy-MM-dd HH:mm:ss)
     * @return String 日期字符串
     */
    public static String getDateFormat(Date date, String pattern) {
        if (date == null) {
            return null;
        }
        synchronized (sdf) {
            String str = null;
            sdf.applyPattern(pattern);
            str = sdf.format(date);
            return str;
        }
    }

    /**
     * 根据时间字符串和对应的格式输出时间(Calendar)类型,如果时间字符串和格式不匹配则出现异常
     *
     * @param strDate 时间字符串
     * @param pattern 时间字符串对应的格式pattern
     * @return java.utils.Calendar
     */
    public static Calendar parseCalendarFormat(String strDate, String pattern) {
        synchronized (sdf) {
            Calendar cal = null;
            sdf.applyPattern(pattern);
            try {
                sdf.parse(strDate);
                cal = sdf.getCalendar();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return cal;
        }
    }

    /**
     * 根据时间字符串和对应的格式输出时间(Date)类型,如果时间字符串和格式不匹配则出现异常
     *
     * @param strDate 时间字符串
     * @param pattern 时间字符串对应的格式pattern
     * @return java.utils.Date
     */
    public static Date parseDateFormat(String strDate, String pattern) {
        if (strDate == null || strDate.trim().length() == 0) {
            return null;
        }
        synchronized (sdf) {
            StringBuffer datebuf = new StringBuffer();
            datebuf.append(strDate);
            if (strDate.length() == 10) {
                datebuf.deleteCharAt(7);
                datebuf.deleteCharAt(4);
            }

            Date date = null;
            sdf.applyPattern(pattern);
            try {
                date = sdf.parse(datebuf.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return date;
        }
    }

    /**
     * 得到本年输入月份的最后一天数（如果说是2月闰年则返回29，2月平年则返回28）
     *
     * @param month 月份
     * @return int 这个月份的最后一天数，如果月份不存在则返回-1
     */
    public static int getLastDayOfMonth(int month) {
        if (month < 1 || month > 12) {
            return -1;
        }
        int retn = 0;
        if (month == 2) {
            if (isLeapYear()) {
                retn = 29;
            } else {
                retn = dayArray[month - 1];
            }
        } else {
            retn = dayArray[month - 1];
        }
        return retn;
    }

    /**
     * 得到输入年输入月份的最后一天数（如果说是2月闰年则返回29，2月平年则返回28）
     *
     * @param year 年
     * @param month 月
     * @return int 这一年这个月份的最后一天数，如果月份不存在则返回-1
     */
    public static int getLastDayOfMonth(int year, int month) {
        if (month < 1 || month > 12) {
            return -1;
        }
        int retn = 0;
        if (month == 2) {
            if (isLeapYear(year)) {
                retn = 29;
            } else {
                retn = dayArray[month - 1];
            }
        } else {
            retn = dayArray[month - 1];
        }
        return retn;
    }

    /**
     * 判断是否是闰年，如果是闰年则返回true否则返回FALSE
     *
     * @return Boolean 如果是闰年则返回true否则返回FALSE
     */
    public static boolean isLeapYear() {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        return isLeapYear(year);
    }

    /**
     * 判断是否是闰年，如果是闰年则返回true否则返回FALSE
     *
     * @param year 年
     * @return 如果是闰年则返回true否则返回FALSE
     */
    public static boolean isLeapYear(int year) {
        /**
         * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年
         * 3.能被4整除同时能被100整除则不是闰年
         */
        if ((year % 400) == 0) {
            return true;
        } else if ((year % 4) == 0) {
            if ((year % 100) == 0) {
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    }

    /**
     * 判断指定日期的年份是否是闰年
     *
     * @param date 指定日期。
     * @return 是否闰年, 如果是闰年则返回true否则返回FALSE
     */
    public static boolean isLeapYear(Date date) {
        /**
         * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年
         * 3.能被4整除同时能被100整除则不是闰年
         */
        // int year = date.getYear();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        int year = gc.get(Calendar.YEAR);
        return isLeapYear(year);
    }

    /**
     * 判断指定日期的年份是否是闰年
     *
     * @param gc 指定日期。
     * @return 是否闰年, 如果是闰年则返回true否则返回FALSE
     */
    public static boolean isLeapYear(Calendar gc) {
        /**
         * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年
         * 3.能被4整除同时能被100整除则不是闰年
         */
        int year = gc.get(Calendar.YEAR);
        return isLeapYear(year);
    }

    /**
     * 得到指定日期的前一个工作日
     *
     * @param date 指定日期。
     * @return 指定日期的前一个工作日
     */
    public static Date getPreviousWeekDay(Date date) {
        {
            /**
             * 详细设计： 1.如果date是星期日，则减3天 2.如果date是星期六，则减2天 3.否则减1天
             */
            GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
            gc.setTime(date);
            return getPreviousWeekDay(gc);
        }
    }

    public static Date getPreviousWeekDay(Calendar gc) {
        {
            /**
             * 详细设计： 1.如果date是星期日，则减3天 2.如果date是星期六，则减2天 3.否则减1天
             */
            switch (gc.get(Calendar.DAY_OF_WEEK)) {
                case (Calendar.MONDAY):
                    gc.add(Calendar.DATE, -3);
                    break;
                case (Calendar.SUNDAY):
                    gc.add(Calendar.DATE, -2);
                    break;
                default:
                    gc.add(Calendar.DATE, -1);
                    break;
            }
            return gc.getTime();
        }
    }

    /**
     * 得到指定日期的后一个工作日
     *
     * @param date 指定日期。
     * @return 指定日期的后一个工作日
     */
    public static Date getNextWeekDay(Date date) {
        /**
         * 详细设计： 1.如果date是星期五，则加3天 2.如果date是星期六，则加2天 3.否则加1天
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, 3);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, 2);
                break;
            default:
                gc.add(Calendar.DATE, 1);
                break;
        }
        return gc.getTime();
    }

    public static Calendar getNextWeekDay(Calendar gc) {
        /**
         * 详细设计： 1.如果date是星期五，则加3天 2.如果date是星期六，则加2天 3.否则加1天
         */
        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, 3);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, 2);
                break;
            default:
                gc.add(Calendar.DATE, 1);
                break;
        }
        return gc;
    }

    /**
     * 取得指定日期的下一个月的最后一天
     *
     * @param date 指定日期。
     * @return 指定日期的下一个月的最后一天
     */
    public static Date getLastDayOfNextMonth(Date date) {
        /**
         * 详细设计： 1.调用getNextMonth设置当前时间 2.以1为基础，调用getLastDayOfMonth
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.setTime(DateUtil.getNextMonth(gc.getTime()));
        gc.setTime(DateUtil.getLastDayOfMonth(gc.getTime()));
        return gc.getTime();
    }

    /**
     * 取得指定日期的下一个星期的最后一天
     *
     * @param date 指定日期。
     * @return 指定日期的下一个星期的最后一天
     */
    public static Date getLastDayOfNextWeek(Date date) {
        /**
         * 详细设计： 1.调用getNextWeek设置当前时间 2.以1为基础，调用getLastDayOfWeek
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.setTime(DateUtil.getNextWeek(gc.getTime()));
        gc.setTime(DateUtil.getLastDayOfWeek(gc.getTime()));
        return gc.getTime();
    }

    /**
     * 取得指定日期的上一个星期的周一
     * @return
     */
    public static Date getMondayOfThisWeek(Date date){
        /**
         * 详细设计：
         * 1.获取上周当前时间
         *          * 1.如果date是星期日，则减6天
         *          * 2.如果date是星期一，则减0天
         *          * 3.如果date是星期二，则减1天
         *          * 4.如果date是星期三，则减2天
         *          * 5.如果date是星期四，则减3天
         *          * 6.如果date是星期五，则减4天
         *          * 7.如果date是星期六，则减5天
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);

        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.SUNDAY):
                gc.add(Calendar.DATE, -6);
                break;
            case (Calendar.MONDAY):
                gc.add(Calendar.DATE, 0);
                break;
            case (Calendar.TUESDAY):
                gc.add(Calendar.DATE, -1);
                break;
            case (Calendar.WEDNESDAY):
                gc.add(Calendar.DATE, -2);
                break;
            case (Calendar.THURSDAY):
                gc.add(Calendar.DATE, -3);
                break;
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, -4);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, -5);
                break;
        }
        return gc.getTime();
    }

    /**
     * 获取星期几
     *
     * @param date
     * @return
     */
    public static int getWhatDay(Date date) {
        /**
         * 详细设计：
         * 1.获取上周当前时间
         *          * 1.如果date是星期日，则减6天
         *          * 2.如果date是星期一，则减0天
         *          * 3.如果date是星期二，则减1天
         *          * 4.如果date是星期三，则减2天
         *          * 5.如果date是星期四，则减3天
         *          * 6.如果date是星期五，则减4天
         *          * 7.如果date是星期六，则减5天
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);

        return gc.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * 取得指定日期的上一个星期的周一
     * @return
     */
    public static Date getMondayOfLastWeek(Date date){
        /**
         * 详细设计：
         * 1.获取上周当前时间
         *          * 1.如果date是星期日，则减6天
         *          * 2.如果date是星期一，则减0天
         *          * 3.如果date是星期二，则减1天
         *          * 4.如果date是星期三，则减2天
         *          * 5.如果date是星期四，则减3天
         *          * 6.如果date是星期五，则减4天
         *          * 7.如果date是星期六，则减5天
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.DATE, -7);

        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.SUNDAY):
                gc.add(Calendar.DATE, -6);
                break;
            case (Calendar.MONDAY):
                gc.add(Calendar.DATE, 0);
                break;
            case (Calendar.TUESDAY):
                gc.add(Calendar.DATE, -1);
                break;
            case (Calendar.WEDNESDAY):
                gc.add(Calendar.DATE, -2);
                break;
            case (Calendar.THURSDAY):
                gc.add(Calendar.DATE, -3);
                break;
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, -4);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, -5);
                break;
        }
        return gc.getTime();
    }

    /**
     * 取得指定日期的上一个星期的周日
     * @return
     */
    public static Date getSundayOfLastWeek(Date date){
        /**
         * 详细设计：
         * 1.获取上周当前时间
         *          * 1.如果date是星期日，则加0天
         *          * 2.如果date是星期一，则加6天
         *          * 3.如果date是星期二，则减5天
         *          * 4.如果date是星期三，则减4天
         *          * 5.如果date是星期四，则减3天
         *          * 6.如果date是星期五，则减2天
         *          * 7.如果date是星期六，则减1天
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.DATE, -7);

        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.SUNDAY):
                gc.add(Calendar.DATE, 0);
                break;
            case (Calendar.MONDAY):
                gc.add(Calendar.DATE, 6);
                break;
            case (Calendar.TUESDAY):
                gc.add(Calendar.DATE, 5);
                break;
            case (Calendar.WEDNESDAY):
                gc.add(Calendar.DATE, 4);
                break;
            case (Calendar.THURSDAY):
                gc.add(Calendar.DATE, 3);
                break;
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, 2);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, 1);
                break;
        }
        return gc.getTime();
    }

    /**
     * 取得指定日期的下一个月的第一天
     *
     * @param date 指定日期。
     * @return 指定日期的下一个月的第一天
     */
    public static Date getFirstDayOfNextMonth(Date date) {
        /**
         * 详细设计： 1.调用getNextMonth设置当前时间 2.以1为基础，调用getFirstDayOfMonth
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.setTime(DateUtil.getNextMonth(gc.getTime()));
        gc.setTime(DateUtil.getFirstDayOfMonth(gc.getTime()));
        return gc.getTime();
    }

    /**
     * 指定时间下一个月份的第一天
     */
    public static Calendar getFirstDayOfNextMonth(Calendar gc) {
        /**
         * 详细设计： 1.调用getNextMonth设置当前时间 2.以1为基础，调用getFirstDayOfMonth
         */
        gc.setTime(DateUtil.getNextMonth(gc.getTime()));
        gc.setTime(DateUtil.getFirstDayOfMonth(gc.getTime()));
        return gc;
    }

    /**
     * 取得指定日期的下一个星期的第一天
     *
     * @param date 指定日期。
     * @return 指定日期的下一个星期的第一天
     */
    public static Date getFirstDayOfNextWeek(Date date) {
        /**
         * 详细设计： 1.调用getNextWeek设置当前时间 2.以1为基础，调用getFirstDayOfWeek
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.setTime(DateUtil.getNextWeek(gc.getTime()));
        gc.setTime(DateUtil.getFirstDayOfWeek(gc.getTime()));
        return gc.getTime();
    }

    /**
     * 指定时间下一个星期的第一天
     */
    public static Calendar getFirstDayOfNextWeek(Calendar gc) {
        /**
         * 详细设计： 1.调用getNextWeek设置当前时间 2.以1为基础，调用getFirstDayOfWeek
         */
        gc.setTime(DateUtil.getNextWeek(gc.getTime()));
        gc.setTime(DateUtil.getFirstDayOfWeek(gc.getTime()));
        return gc;
    }

    /**
     * 指定日期加1年
     */
    public static Date getNextYear(Date date) {
        /**
         * 详细设计： 1.指定日期加1年
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.YEAR, 1);
        return gc.getTime();
    }

    /**
     * 指定日期加1年
     */
    public static Calendar getNextYear(Calendar gc) {
        /**
         * 详细设计： 1.指定日期加1年
         */
        gc.add(Calendar.YEAR, 1);
        return gc;
    }

    /**
     * 取得指定日期的下一个月
     *
     * @param date 指定日期。
     * @return 指定日期的下一个月
     */
    public static Date getNextMonth(Date date) {
        /**
         * 详细设计： 1.指定日期的月份加1
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.MONTH, 1);
        return gc.getTime();
    }

    /**
     * 详细设计： 1.指定日期的月份加1
     */
    public static Calendar getNextMonth(Calendar gc) {
        gc.add(Calendar.MONTH, 1);
        return gc;
    }

    /**
     * 详细设计： 1.指定日期加1天
     *
     * @param date 指定日期。
     * @return 指定日期的下一天
     */
    public static Date getNextDay(Date date) {

        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.DATE, 1);
        return gc.getTime();
    }

    /**
     * 详细设计： 1.指定日期加1天
     */
    public static Calendar getNextDay(Calendar gc) {
        gc.add(Calendar.DATE, 1);
        return gc;
    }

    /**
     * 详细设计： 1.指定日期减1天
     */
    public static Date getPreviousDay(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.DATE, -1);
        return gc.getTime();
    }

    /**
     * 详细设计： 1.指定日期减1天
     */
    public static Calendar getPreviousDay(Calendar gc) {
        gc.add(Calendar.DATE, -1);
        return gc;
    }

    /**
     * 取得指定日期的下一个星期
     *
     * @param date 指定日期。
     * @return 指定日期的下一个星期
     */
    public static Date getNextWeek(Date date) {
        /**
         * 详细设计： 1.指定日期加7天
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.DATE, 7);
        return gc.getTime();
    }

    /**
     * 取得指定日期的n天
     *
     * @param date 指定日期。
     * @return 指定日期的n天
     */
    public static Date getNextNumDay(Date date, int n) {
        /**
         * 详细设计： 1.指定日期加n天
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.add(Calendar.DATE, n);
        return gc.getTime();
    }

    /**
     * 指定日期加7天
     */
    public static Calendar getNextWeek(Calendar gc) {
        /**
         * 详细设计： 1.指定日期加7天
         */
        gc.add(Calendar.DATE, 7);
        return gc;
    }

    /**
     * 取得指定日期的所处星期的最后一天
     *
     * @param date 指定日期。
     * @return 指定日期的所处星期的最后一天
     */
    public static Date getLastDayOfWeek(Date date) {
        /**
         * 详细设计：
         * 1.如果date是星期日，则加6天
         * 2.如果date是星期一，则加5天
         * 3.如果date是星期二，则加4天
         * 4.如果date是星期三，则加3天
         * 5.如果date是星期四，则加2天
         * 6.如果date是星期五，则加1天
         * 7.如果date是星期六，则加0天
         */
        Calendar gc = Calendar.getInstance();
        gc.setTime(date);
        gc = getLastDayOfWeek(gc);
        return gc.getTime();
    }

    public static Calendar getLastDayOfWeek(Calendar gc) {
        /**
         * 详细设计：
         * 1.如果date是星期日，则加6天
         * 2.如果date是星期一，则加5天
         * 3.如果date是星期二，则加4天
         * 4.如果date是星期三，则加3天
         * 5.如果date是星期四，则加2天
         * 6.如果date是星期五，则加1天
         * 7.如果date是星期六，则加0天
         */
        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.SUNDAY):
                gc.add(Calendar.DATE, 6);
                break;
            case (Calendar.MONDAY):
                gc.add(Calendar.DATE, 5);
                break;
            case (Calendar.TUESDAY):
                gc.add(Calendar.DATE, 4);
                break;
            case (Calendar.WEDNESDAY):
                gc.add(Calendar.DATE, 3);
                break;
            case (Calendar.THURSDAY):
                gc.add(Calendar.DATE, 2);
                break;
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, 1);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, 0);
                break;
        }
        return gc;
    }

    /**
     * 取得指定日期的所处星期的第一天
     *
     * @param date 指定日期。
     * @return 指定日期的所处星期的第一天
     */
    public static Date getFirstDayOfWeek(Date date) {
        /**
         * 详细设计：
         * 1.如果date是星期日，则减0天
         * 2.如果date是星期一，则减1天
         * 3.如果date是星期二，则减2天
         * 4.如果date是星期三，则减3天
         * 5.如果date是星期四，则减4天
         * 6.如果date是星期五，则减5天
         * 7.如果date是星期六，则减6天
         */
        Calendar gc = Calendar.getInstance();
        gc.setTime(date);
        gc = getFirstDayOfWeek(gc);
        return gc.getTime();
    }

    /**
     * 取得指定日期的所处星期的第一天
     *
     * @param gc 指定日期。
     * @return 指定日期的所处星期的第一天
     */
    public static Calendar getFirstDayOfWeek(Calendar gc) {
        /**
         * 详细设计：
         * 1.如果date是星期日，则减0天
         * 2.如果date是星期一，则减1天
         * 3.如果date是星期二，则减2天
         * 4.如果date是星期三，则减3天
         * 5.如果date是星期四，则减4天
         * 6.如果date是星期五，则减5天
         * 7.如果date是星期六，则减6天
         */
        switch (gc.get(Calendar.DAY_OF_WEEK)) {
            case (Calendar.SUNDAY):
                gc.add(Calendar.DATE, 0);
                break;
            case (Calendar.MONDAY):
                gc.add(Calendar.DATE, -1);
                break;
            case (Calendar.TUESDAY):
                gc.add(Calendar.DATE, -2);
                break;
            case (Calendar.WEDNESDAY):
                gc.add(Calendar.DATE, -3);
                break;
            case (Calendar.THURSDAY):
                gc.add(Calendar.DATE, -4);
                break;
            case (Calendar.FRIDAY):
                gc.add(Calendar.DATE, -5);
                break;
            case (Calendar.SATURDAY):
                gc.add(Calendar.DATE, -6);
                break;
        }
        return gc;
    }

    /**
     * 取得指定日期的所处月份的最后一天
     *
     * @param date 指定日期。
     * @return 指定日期的所处月份的最后一天
     */
    public static Date getLastDayOfMonth(Date date) {
        /**
         * 详细设计： 1.如果date在1月，则为31日 2.如果date在2月，则为28日 3.如果date在3月，则为31日 4.如果date在4月，则为30日
         * 5.如果date在5月，则为31日 6.如果date在6月，则为30日 7.如果date在7月，则为31日 8.如果date在8月，则为31日
         * 9.如果date在9月，则为30日 10.如果date在10月，则为31日 11.如果date在11月，则为30日 12.如果date在12月，则为31日
         * 1.如果date在闰年的2月，则为29日
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        switch (gc.get(Calendar.MONTH)) {
            case 0:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 1:
                gc.set(Calendar.DAY_OF_MONTH, 28);
                break;
            case 2:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 3:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 4:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 5:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 6:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 7:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 8:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 9:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 10:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 11:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
        }
        // 检查闰年
        if ((gc.get(Calendar.MONTH) == Calendar.FEBRUARY) && (isLeapYear(gc.get(Calendar.YEAR)))) {
            gc.set(Calendar.DAY_OF_MONTH, 29);
        }
        return gc.getTime();
    }

    /**
     * 取得指定日期的所处月份的最后一天
     *
     * @param gc 指定日期。
     * @return 指定日期的所处月份的最后一天
     */
    public static Calendar getLastDayOfMonth(Calendar gc) {
        /**
         * 详细设计： 1.如果date在1月，则为31日 2.如果date在2月，则为28日 3.如果date在3月，则为31日 4.如果date在4月，则为30日
         * 5.如果date在5月，则为31日 6.如果date在6月，则为30日 7.如果date在7月，则为31日 8.如果date在8月，则为31日
         * 9.如果date在9月，则为30日 10.如果date在10月，则为31日 11.如果date在11月，则为30日 12.如果date在12月，则为31日
         * 1.如果date在闰年的2月，则为29日
         */
        switch (gc.get(Calendar.MONTH)) {
            case 0:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 1:
                gc.set(Calendar.DAY_OF_MONTH, 28);
                break;
            case 2:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 3:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 4:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 5:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 6:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 7:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 8:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 9:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
            case 10:
                gc.set(Calendar.DAY_OF_MONTH, 30);
                break;
            case 11:
                gc.set(Calendar.DAY_OF_MONTH, 31);
                break;
        }
        // 检查闰年
        if ((gc.get(Calendar.MONTH) == Calendar.FEBRUARY) && (isLeapYear(gc.get(Calendar.YEAR)))) {
            gc.set(Calendar.DAY_OF_MONTH, 29);
        }
        return gc;
    }

    /**
     * 取得指定日期的所处月份的第一天
     *
     * @param date 指定日期。
     * @return 指定日期的所处月份的第一天
     */
    public static Date getFirstDayOfMonth(Date date) {
        /**
         * 详细设计： 1.设置为1号
         */
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.set(Calendar.DAY_OF_MONTH, 1);
        return gc.getTime();
    }

    /**
     * 取得指定日期的所处月份的第一天
     *
     * @param gc 指定日期。
     * @return 指定日期的所处月份的第一天
     */
    public static Calendar getFirstDayOfMonth(Calendar gc) {
        /**
         * 详细设计： 1.设置为1号
         */
        gc.set(Calendar.DAY_OF_MONTH, 1);
        return gc;
    }

    /**
     * 将日期对象转换成为指定ORA日期、时间格式的字符串形式。如果日期对象为空，返回 一个空字符串对象，而不是一个空对象。
     *
     * @param theDate 将要转换为字符串的日期对象。
     * @param hasTime 如果返回的字符串带时间则为true
     * @return 转换的结果
     */
    public static String toOraString(Date theDate, boolean hasTime) {
        /**
         * 详细设计： 1.如果有时间，则设置格式为getOraDateTimeFormat()的返回值
         * 2.否则设置格式为getOraDateFormat()的返回值 3.调用toString(Date theDate, DateFormat
         * theDateFormat)
         */
        DateFormat theFormat;
        if (hasTime) {
            theFormat = getOraDateTimeFormat();
        } else {
            theFormat = getOraDateFormat();
        }
        return toString(theDate, theFormat);
    }

    /**
     * 将日期对象转换成为指定日期、时间格式的字符串形式。如果日期对象为空，返回 一个空字符串对象，而不是一个空对象。
     *
     * @param theDate 将要转换为字符串的日期对象。
     * @param hasTime 如果返回的字符串带时间则为true
     * @return 转换的结果
     */
    public static String toString(Date theDate, boolean hasTime) {
        /**
         * 详细设计： 1.如果有时间，则设置格式为getDateTimeFormat的返回值 2.否则设置格式为getDateFormat的返回值
         * 3.调用toString(Date theDate, DateFormat theDateFormat)
         */
        DateFormat theFormat;
        if (hasTime) {
            theFormat = getDateTimeFormat();
        } else {
            theFormat = getDateFormat();
        }
        return toString(theDate, theFormat);
    }


    /**
     * 创建一个标准日期格式的克隆
     *
     * @return 标准日期格式的克隆
     */
    public static DateFormat getDateFormat() {
        /**
         * 详细设计： 1.返回DATE_FORMAT
         */
        SimpleDateFormat theDateFormat = (SimpleDateFormat) DATE_FORMAT.clone();
        theDateFormat.setLenient(false);
        return theDateFormat;
    }

    /**
     * 创建一个标准时间格式的克隆
     *
     * @return 标准时间格式的克隆
     */
    public static DateFormat getDateTimeFormat() {
        /**
         * 详细设计： 1.返回DATE_TIME_FORMAT
         */
        SimpleDateFormat theDateTimeFormat = (SimpleDateFormat) DATE_TIME_FORMAT.clone();
        theDateTimeFormat.setLenient(false);
        return theDateTimeFormat;
    }

    /**
     * 创建一个标准ORA日期格式的克隆
     *
     * @return 标准ORA日期格式的克隆
     */
    public static DateFormat getOraDateFormat() {
        /**
         * 详细设计： 1.返回ORA_DATE_FORMAT
         */
        SimpleDateFormat theDateFormat = (SimpleDateFormat) ORA_DATE_FORMAT.clone();
        theDateFormat.setLenient(false);
        return theDateFormat;
    }

    /**
     * 创建一个标准ORA时间格式的克隆
     *
     * @return 标准ORA时间格式的克隆
     */
    public static DateFormat getOraDateTimeFormat() {
        /**
         * 详细设计： 1.返回ORA_DATE_TIME_FORMAT
         */
        SimpleDateFormat theDateTimeFormat = (SimpleDateFormat) ORA_DATE_TIME_FORMAT.clone();
        theDateTimeFormat.setLenient(false);
        return theDateTimeFormat;
    }

    /**
     * 将一个日期对象转换成为指定日期、时间格式的字符串。 如果日期对象为空，返回一个空字符串，而不是一个空对象。
     *
     * @param theDate 要转换的日期对象
     * @param theDateFormat 返回的日期字符串的格式
     * @return 转换结果
     */
    public static String toString(Date theDate, DateFormat theDateFormat) {
        /**
         * 详细设计： 1.theDate为空，则返回"" 2.否则使用theDateFormat格式化
         */
        if (theDate == null) {
            return "";
        }
        return theDateFormat.format(theDate);
    }

    /**
     * 计算两个日期之间相差的月个数，不足一个月忽略
     */
    public static int subMonth(Calendar begingc, Calendar endgc) {
        int beginYear = begingc.get(Calendar.YEAR);
        int beginMonth = begingc.get(Calendar.MONTH);
        int endYear = endgc.get(Calendar.YEAR);
        int endMonth = endgc.get(Calendar.MONTH);
        return (endYear - beginYear) * 12 + (endMonth - beginMonth);
    }

    /**
     * 计算两个日期之间相差的整月数,日期是××××年××月××日００时００分００秒 如果不足一个月按照一个月计算
     */
    public static int betweenMonths(Date begin, Date end) {
        Calendar begingc = Calendar.getInstance();
        begingc.setTime(begin);
        int beginYear = begingc.get(Calendar.YEAR);
        int beginMonth = begingc.get(Calendar.MONTH);
        int beginDay = begingc.get(Calendar.DAY_OF_MONTH);

        Calendar endgc = Calendar.getInstance();
        endgc.setTime(end);
        int endYear = endgc.get(Calendar.YEAR);
        int endMonth = endgc.get(Calendar.MONTH);
        int endDay = endgc.get(Calendar.DAY_OF_MONTH);

        int between = (endYear - beginYear) * 12 + (endMonth - beginMonth);

        if (endDay > beginDay) {
            between = between + 1;
        } else if (endDay < beginDay) {
            between = between - 1;
        }
        return between;

    }

    /**
     * 计算两个日期之间年数
     *
     * @deprecated
     */
    public static double distanceYear(String beginDate, String endDate) {
        if (beginDate == null || beginDate.trim().length() == 0 || endDate == null || endDate.trim().length() == 0) {
            return 0;
        }
        int yday = 365;
        double disYear = 0.0;
        String pattern = "yyyy-MM-dd";

        Calendar bcal = parseCalendarFormat(beginDate, pattern);
        int bday = bcal.get(Calendar.DAY_OF_YEAR);

        Calendar ecal = parseCalendarFormat(endDate, pattern);
        int eday = ecal.get(Calendar.DAY_OF_YEAR);

        if (isLeapYear(Integer.parseInt(beginDate.substring(0, 4)))) {
            yday = 366;
            disYear = (yday - bday + eday) / yday;
        } else {
            disYear = (double) (yday - bday + eday) / yday;
        }
        return disYear;
    }

    /**
     * 忽略闰年计算两时间之间天数
     *
     * @deprecated
     */
    public static int calculeteBetweenDays(Date begin, Date end) {
        if (begin == null || end == null) {
            return 0;
        }
        Calendar cal = Calendar.getInstance();
        int beginYear = begin.getYear();
        int endYear = end.getYear();
        cal.setTime(begin);
        int beginDay = cal.get(Calendar.DAY_OF_YEAR);
        cal.setTime(end);
        int endDay = cal.get(Calendar.DAY_OF_YEAR);
        return (365) * (endYear - beginYear) + (endDay - beginDay);

    }

    /**
     * 计算两时间之间年
     *
     * @deprecated
     */
    public static double calculateBetweenYears(Date begin, Date end) {
        return (double) calculeteBetweenDays(begin, end) / 365;
    }

    /**
     * 计算两个日期之间的年份，日期是××××年××月××日００时００分００秒 不足一个月按照一个月计算
     */
    public static double betweenYears(Date begin, Date end) {
        return betweenMonths(begin, end) / 12.0;
    }

    /**
     * 转换日期格式
     *
     * @param date Date
     * @param simple SimpleDateFormat
     */
    public static String transDateToString(Date date, SimpleDateFormat simple) {
        if (date == null) {
            return null;
        }
        return simple.format(date);
    }

    /**
     * 转换日期格式
     *
     * @param date Date
     */
    public static String transDateToString(Date date, String format) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat simple = new SimpleDateFormat(format);
        return simple.format(date);
    }

    /**
     * @param s
     * @return
     * @throws ParseException
     */
    public static Date transStringToDate(String s) throws ParseException {
        if (s == null || s.trim().equals("")) {
            return null;
        }
        return SimpleDateFormat.getDateInstance().parse(s);
    }

    /**
     * 将day和time拼接转换成Date格式
     *
     * @param day yyyyMMdd
     * @param time HHmmss(可以为null)
     */
    public static Date getBankCardDate(String day, String time) {
        if (day == null || "".equals(day.trim())) {
            return null;
        }
        if (time == null || "".equals(time.trim())) {
            time = "000000";
        }
        String strDate = day + time;
        String pattern = "yyyyMMddHHmmss";
        return parseDateFormat(strDate, pattern);
    }

    public static long getIntervalDays(Date beginDate, Date endDate) {
        long days = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
        return days;
    }

    /**
     * 只有数字的日期字符串转化为Date
     *
     * @param stringDate 只有数字的日期字符串
     * @return Date
     * @see
     */
    public static Date fromString(String stringDate) {
        if (stringDate == null || stringDate.length() == 0) {
            return null;
        }

        int length = stringDate.length();
        String dateFm;
        if (length == 8) {
            dateFm = "yyyyMMdd"; // 格式化当前系统日期到天
        } else if (length == 10) {
            dateFm = "yyyyMMddHH";// 格式化当前系统日期到时
        } else if (length == 12) {
            dateFm = "yyyyMMddHHmm"; // 格式化当前系统日期到分钟
        } else if (length == 14) {
            dateFm = "yyyyMMddHHmmss"; // 格式化当前系统日期到秒
        } else {
            dateFm = "yyyyMM";
        }
        return DateUtil.parseDateFormat(stringDate, dateFm);
    }

    /**
     * 获取日期的凌晨时间 (yyyy-MM-dd 00:00:00)
     */
    public static String getBeginDate(Date date) {
        String pattern = "yyyy-MM-dd 00:00:00";
        return getDateFormat(date, pattern);
    }

    /**
     * 获取日期的午夜时间 (yyyy-MM-dd 23:59:59)
     */
    public static String getPolicyEndDate(Date date) {
        String pattern = "yyyy-MM-dd 23:59:59";
        return getDateFormat(date, pattern);
    }


    public static DateTimeFormatter getDateTimeFormatter() {
        return dateFormatter;
    }

    /**
     * 获取现在时间
     *
     * @return 返回时间类型 yyyy-MM-dd HH:mm:ss
     */
    public static Date getNowDate() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(new Date());
        ParsePosition pos = new ParsePosition(8);
        Date currentTime_2 = formatter.parse(dateString, pos);
        return currentTime_2;
    }

    /**
     * 获取现在时间
     *
     * @return返回短时间格式 yyyy-MM-dd
     */
    public static Date getNowDateShort() {
        String dateString = formatter.format(new Date());
        ParsePosition pos = new ParsePosition(8);
        Date currentTime_2 = formatter.parse(dateString, pos);
        return currentTime_2;
    }

    /**
     * 获取现在时间
     *
     * @return返回字符串格式 yyyy-MM-dd HH:mm:ss
     */
    public static String getStringDate() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(new Date());
        return dateString;
    }

    /**
     * 获取现在时间
     *
     * @return返回字符串格式 yyyyMMddHHmmss
     */
    public static String getStringAllDate() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String dateString = formatter.format(new Date());
        return dateString;
    }

    /**
     * 获取现在时间
     *
     * @return 返回短时间字符串格式yyyy-MM-dd
     */
    public static String getStringDateShort() {
        String dateString = formatter.format(new Date());
        return dateString;
    }

    /**
     * 获取时间 小时:分;秒 HH:mm:ss
     */
    public static String getTimeShort() {
        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
        String dateString = formatter.format(new Date());
        return dateString;
    }

    /**
     * 将长时间格式字符串转换为时间 yyyy-MM-dd HH:mm:ss
     */
    public static Date strToDateLong(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }

    /**
     * 将长时间格式时间转换为字符串 yyyy-MM-dd HH:mm:ss
     */
    public static String dateToStrLong(Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    /**
     * 将短时间格式时间转换为字符串 yyyy-MM-dd
     */
    public static String dateToStr(Date dateDate) {
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    public static String dateToStr(java.time.LocalDate dateDate) {
        String dateString = dateFormatter.format(dateDate);
        return dateString;
    }

    /**
     * 将短时间格式字符串转换为时间 yyyy-MM-dd
     */
    public static Date strToDate(String strDate) {
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }

    /**
     * 将短时间格式字符串转换为时间 yyyy-MM-dd HH:mm:ss
     */
    public static Timestamp strToDateSql(String strDate) {
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter2.parse(strDate, pos);
        return new Timestamp(strtodate.getTime());
    }

    /**
     * 得到现在时间
     */
    public static Date getNow() {
        Date currentTime = new Date();
        return currentTime;
    }

    /**
     * 提取一个月中的最后一天
     */
    public static Date getLastDate(long day) {
        Date date = new Date();
        long date_3_hm = date.getTime() - 3600000 * 34 * day;
        Date date_3_hm_date = new Date(date_3_hm);
        return date_3_hm_date;
    }

    /**
     * 得到现在时间
     *
     * @return 字符串 yyyyMMdd HHmmss
     */
    public static String getStringToday() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd HHmmss");
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * 功能：<br/>
     *
     * @author Tony
     * @version 2016年12月16日 下午4:41:51 <br/>
     */
    public static String getTodayShort() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * @param @param value
     * @return String
     * @Description: 输入一个整数类型的字符串, 然后转换成时分秒的形式输出 例如：输入568 返回结果为：00:09:28 输入null或者“” 返回结果为:00:00:00
     * @author Tony 鬼手卡卡
     * @date 2016-4-20
     */
    public static String getHHMMSS(String value) {
        String hour = "00";
        String minute = "00";
        String second = "00";
        if (value != null && !value.trim().equals("")) {
            int v_int = Integer.parseInt(value);
            hour = v_int / 3600 + "";//获得小时;
            minute = v_int % 3600 / 60 + "";//获得小时;
            second = v_int % 3600 % 60 + "";//获得小时;
        }
        return (hour.length() > 1 ? hour : "0" + hour) + ":" + (minute.length() > 1 ? minute : "0" + minute) + ":" + (
            second.length() > 1 ? second : "0" + second);
    }

    /**
     * 得到现在小时
     */
    public static String getHour() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(currentTime);
        String hour;
        hour = dateString.substring(11, 13);
        return hour;
    }

    /**
     * 得到现在分钟
     */
    public static String getMinTime() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(currentTime);
        String min;
        min = dateString.substring(14, 16);
        return min;
    }

    /**
     * 根据用户传入的时间表示格式，返回当前时间的格式 如果是yyyyMMdd，注意字母y不能大写。
     *
     * @param sformat yyyyMMddhhmmss
     */
    public static String getUserDate(String sformat) {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(sformat);
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * 二个小时时间间的差值,必须保证二个时间都是"HH:MM"的格式，返回字符型的分钟
     */
    public static String getTwoHour(String st1, String st2) {
        String[] kk = null;
        String[] jj = null;
        kk = st1.split(":");
        jj = st2.split(":");
        if (Integer.parseInt(kk[0]) < Integer.parseInt(jj[0])) {
            return "0";
        } else {
            double y = Double.parseDouble(kk[0]) + Double.parseDouble(kk[1]) / 60;
            double u = Double.parseDouble(jj[0]) + Double.parseDouble(jj[1]) / 60;
            if ((y - u) > 0) {
                return y - u + "";
            } else {
                return "0";
            }
        }
    }

    /**
     * 得到二个日期间的间隔天数
     */
    public static String getTwoDay(String sj1, String sj2) {
        long day = 0;
        try {
            Date date = formatter.parse(sj1);
            Date mydate = formatter.parse(sj2);
            day = (date.getTime() - mydate.getTime()) / (24 * 60 * 60 * 1000);
        } catch (Exception e) {
            return "";
        }
        return day + "";
    }

    /**
     * 时间前推或后推分钟,其中JJ表示分钟.
     */
    public static String getPreTime(String sj1, String jj) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String mydate1 = "";
        try {
            Date date1 = format.parse(sj1);
            long Time = (date1.getTime() / 1000) + Integer.parseInt(jj) * 60;
            date1.setTime(Time * 1000);
            mydate1 = format.format(date1);
        } catch (Exception e) {
        }
        return mydate1;
    }

    /**
     * 得到一个时间延后或前移几天的时间,nowdate(yyyy-mm-dd)为时间,delay为前移或后延的天数
     */
    public static String getNextDay(String nowdate, String delay) {
        try {
            String mdate = "";
            Date d = strToDate(nowdate);
            long myTime = (d.getTime() / 1000) + Integer.parseInt(delay) * 24 * 60 * 60;
            d.setTime(myTime * 1000);
            mdate = formatter.format(d);
            return mdate;
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 功能：<br/> 距离现在几天的时间是多少 获得一个时间字符串，格式为：yyyy-MM-dd HH:mm:ss day  如果为整数，表示未来时间 如果为负数，表示过去时间
     *
     * @author Tony
     * @version 2016年11月29日 上午11:02:56 <br/>
     */
    public static String getFromNow(int day) {
        Date date = new Date();
        long dateTime = (date.getTime() / 1000) + day * 24 * 60 * 60;
        date.setTime(dateTime * 1000);
        return formatter2.format(date);
    }

    /**
     * 判断是否润年
     */
    public static boolean isLeapYear(String ddate) {

        /**
         * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年
         * 3.能被4整除同时能被100整除则不是闰年
         */
        Date d = strToDate(ddate);
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(d);
        int year = gc.get(Calendar.YEAR);
        if ((year % 400) == 0) {
            return true;
        } else if ((year % 4) == 0) {
            if ((year % 100) == 0) {
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    }

    /**
     * 返回美国时间格式 26 Apr 2006
     */
    public static String getEDate(String str) {
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(str, pos);
        String j = strtodate.toString();
        String[] k = j.split(" ");
        return k[2] + k[1].toUpperCase() + k[5].substring(2, 4);
    }

    /**
     * 获取一个月的最后一天
     */
    public static String getEndDateOfMonth(String dat) {// yyyy-MM-dd
        String str = dat.substring(0, 8);
        String month = dat.substring(5, 7);
        int mon = Integer.parseInt(month);
        if (mon == 1 || mon == 3 || mon == 5 || mon == 7 || mon == 8 || mon == 10 || mon == 12) {
            str += "31";
        } else if (mon == 4 || mon == 6 || mon == 9 || mon == 11) {
            str += "30";
        } else {
            if (isLeapYear(dat)) {
                str += "29";
            } else {
                str += "28";
            }
        }
        return str;
    }

    /**
     * 判断二个时间是否在同一个周
     */
    public static boolean isSameWeekDates(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(date1);
        cal2.setTime(date2);
        int subYear = cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR);
        if (0 == subYear) {
            if (cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR)) {
                return true;
            }
        } else if (1 == subYear && 11 == cal2.get(Calendar.MONTH)) {
            // 如果12月的最后一周横跨来年第一周的话则最后一周即算做来年的第一周
            if (cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR)) {
                return true;
            }
        } else if (-1 == subYear && 11 == cal1.get(Calendar.MONTH)) {
            if (cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 产生周序列,即得到当前时间所在的年度是第几周
     */
    public static String getSeqWeek() {
        Calendar c = Calendar.getInstance(Locale.CHINA);
        String week = Integer.toString(c.get(Calendar.WEEK_OF_YEAR));
        if (week.length() == 1) {
            week = "0" + week;
        }
        String year = Integer.toString(c.get(Calendar.YEAR));
        return year + week;
    }

    /**
     * 获得一个日期所在的周的星期几的日期，如要找出2002年2月3日所在周的星期一是几号
     */
    public static String getWeek(String sdate, String num) {
        // 再转换为时间
        Date dd = strToDate(sdate);
        Calendar c = Calendar.getInstance();
        c.setTime(dd);
        if (num.equals("1")) // 返回星期一所在的日期
        {
            c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        } else if (num.equals("2")) // 返回星期二所在的日期
        {
            c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
        } else if (num.equals("3")) // 返回星期三所在的日期
        {
            c.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
        } else if (num.equals("4")) // 返回星期四所在的日期
        {
            c.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
        } else if (num.equals("5")) // 返回星期五所在的日期
        {
            c.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
        } else if (num.equals("6")) // 返回星期六所在的日期
        {
            c.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
        } else if (num.equals("0")) // 返回星期日所在的日期
        {
            c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        }
        return new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
    }

    /**
     * 根据一个日期，返回是星期几的字符串
     */
    public static String getWeek(String sdate) {
        // 再转换为时间
        Date date = strToDate(sdate);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        // int hour=c.get(Calendar.DAY_OF_WEEK);
        // hour中存的就是星期几了，其范围 1~7
        // 1=星期日 7=星期六，其他类推
        return new SimpleDateFormat("EEEE").format(c.getTime());
    }

    public static String getWeekStr(String sdate) {
        String str = "";
        str = getWeek(sdate);
        if ("1".equals(str)) {
            str = "星期日";
        } else if ("2".equals(str)) {
            str = "星期一";
        } else if ("3".equals(str)) {
            str = "星期二";
        } else if ("4".equals(str)) {
            str = "星期三";
        } else if ("5".equals(str)) {
            str = "星期四";
        } else if ("6".equals(str)) {
            str = "星期五";
        } else if ("7".equals(str)) {
            str = "星期六";
        }
        return str;
    }

    /**
     * 两个时间之间的天数
     */
    public static long getDays(String date1, String date2) {
        if (date1 == null || date1.equals("")) {
            return 0;
        }
        if (date2 == null || date2.equals("")) {
            return 0;
        }
        // 转换为标准时间
        Date date = null;
        Date mydate = null;
        try {
            date = formatter.parse(date1);
            mydate = formatter.parse(date2);
        } catch (Exception e) {
        }
        long day = (date.getTime() - mydate.getTime()) / (24 * 60 * 60 * 1000);
        return day;
    }

    /**
     * 形成如下的日历 ， 根据传入的一个时间返回一个结构 星期日 星期一 星期二 星期三 星期四 星期五 星期六 下面是当月的各个时间 此函数返回该日历第一行星期日所在的日期
     */
    public static String getNowMonth(String sdate) {
        // 取该时间所在月的一号
        sdate = sdate.substring(0, 8) + "01";

        // 得到这个月的1号是星期几
        Date date = strToDate(sdate);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int u = c.get(Calendar.DAY_OF_WEEK);
        String newday = getNextDay(sdate, (1 - u) + "");
        return newday;
    }

    /**
     * 取得数据库主键 生成格式为yyyymmddhhmmss+k位随机数
     *
     * @param k 表示是取几位随机数，可以自己定
     */

    public static String getNo(int k) {

        return getUserDate("yyyyMMddhhmmss") + getRandom(k);
    }

    /**
     * 返回一个随机数
     */
    public static String getRandom(int i) {
        Random jjj = new Random();
        // int suiJiShu = jjj.nextInt(9);
        if (i == 0) {
            return "";
        }
        String jj = "";
        for (int k = 0; k < i; k++) {
            jj = jj + jjj.nextInt(9);
        }
        return jj;
    }

    /**
     * @param date
     */
    public static boolean RightDate(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        if (date == null) {
            return false;
        }
        if (date.length() > 10) {
            sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        } else {
            sdf = new SimpleDateFormat("yyyy-MM-dd");
        }
        try {
            sdf.parse(date);
        } catch (ParseException pe) {
            return false;
        }
        return true;
    }

    /***************************************************************************
     * //nd=1表示返回的值中包含年度 //yf=1表示返回的值中包含月份 //rq=1表示返回的值中包含日期 //format表示返回的格式 1
     * 以年月日中文返回 2 以横线-返回 // 3 以斜线/返回 4 以缩写不带其它符号形式返回 // 5 以点号.返回
     **************************************************************************/
    public static String getStringDateMonth(String sdate, String nd, String yf, String rq, String format) {
        Date currentTime = new Date();
        String dateString = formatter.format(currentTime);
        String s_nd = dateString.substring(0, 4); // 年份
        String s_yf = dateString.substring(5, 7); // 月份
        String s_rq = dateString.substring(8, 10); // 日期
        String sreturn = "";
        //roc.utils.MyChar mc = new roc.utils.MyChar();
        //if (sdate == null || sdate.equals("") || !mc.Isdate(sdate)) { // 处理空值情况
        if (sdate == null || sdate.equals("")) {
            if (nd.equals("1")) {
                sreturn = s_nd;
                // 处理间隔符
                if (format.equals("1")) {
                    sreturn = sreturn + "年";
                } else if (format.equals("2")) {
                    sreturn = sreturn + "-";
                } else if (format.equals("3")) {
                    sreturn = sreturn + "/";
                } else if (format.equals("5")) {
                    sreturn = sreturn + ".";
                }
            }
            // 处理月份
            if (yf.equals("1")) {
                sreturn = sreturn + s_yf;
                if (format.equals("1")) {
                    sreturn = sreturn + "月";
                } else if (format.equals("2")) {
                    sreturn = sreturn + "-";
                } else if (format.equals("3")) {
                    sreturn = sreturn + "/";
                } else if (format.equals("5")) {
                    sreturn = sreturn + ".";
                }
            }
            // 处理日期
            if (rq.equals("1")) {
                sreturn = sreturn + s_rq;
                if (format.equals("1")) {
                    sreturn = sreturn + "日";
                }
            }
        } else {
            // 不是空值，也是一个合法的日期值，则先将其转换为标准的时间格式
            sdate = getOKDate(sdate);
            s_nd = sdate.substring(0, 4); // 年份
            s_yf = sdate.substring(5, 7); // 月份
            s_rq = sdate.substring(8, 10); // 日期
            if (nd.equals("1")) {
                sreturn = s_nd;
                // 处理间隔符
                if (format.equals("1")) {
                    sreturn = sreturn + "年";
                } else if (format.equals("2")) {
                    sreturn = sreturn + "-";
                } else if (format.equals("3")) {
                    sreturn = sreturn + "/";
                } else if (format.equals("5")) {
                    sreturn = sreturn + ".";
                }
            }
            // 处理月份
            if (yf.equals("1")) {
                sreturn = sreturn + s_yf;
                if (format.equals("1")) {
                    sreturn = sreturn + "月";
                } else if (format.equals("2")) {
                    sreturn = sreturn + "-";
                } else if (format.equals("3")) {
                    sreturn = sreturn + "/";
                } else if (format.equals("5")) {
                    sreturn = sreturn + ".";
                }
            }
            // 处理日期
            if (rq.equals("1")) {
                sreturn = sreturn + s_rq;
                if (format.equals("1")) {
                    sreturn = sreturn + "日";
                }
            }
        }
        return sreturn;
    }

    public static String getNextMonthDay(String sdate, int m) {
        sdate = getOKDate(sdate);
        int year = Integer.parseInt(sdate.substring(0, 4));
        int month = Integer.parseInt(sdate.substring(5, 7));
        month = month + m;
        if (month < 0) {
            month = month + 12;
            year = year - 1;
        } else if (month > 12) {
            month = month - 12;
            year = year + 1;
        }
        String smonth = "";
        if (month < 10) {
            smonth = "0" + month;
        } else {
            smonth = "" + month;
        }
        return year + "-" + smonth + "-10";
    }

    /**
     * 功能：<br/>
     *
     * @author Tony
     * @version 2015-3-31 上午09:29:31 <br/>
     */
    public static String getOKDate(String sdate) {
        if (sdate == null || sdate.equals("")) {
            return getStringDateShort();
        }

//   if (!VeStr.Isdate(sdate)) {
//    sdate = getStringDateShort();
//   }
//   // 将“/”转换为“-”
//   sdate = VeStr.Replace(sdate, "/", "-");
        // 如果只有8位长度，则要进行转换
        if (sdate.length() == 8) {
            sdate = sdate.substring(0, 4) + "-" + sdate.substring(4, 6) + "-" + sdate.substring(6, 8);
        }
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(sdate, pos);
        String dateString = formatter.format(strtodate);
        return dateString;
    }

    /**
     * 获取当前时间的前一天时间
     */
    private static String getBeforeDay(Calendar cl) {
        //使用roll方法进行向前回滚
        //cl.roll(Calendar.DATE, -1);
        //使用set方法直接进行设置
        // int day = cl.get(Calendar.DATE);
        cl.add(Calendar.DATE, -1);
        return formatter.format(cl.getTime());
    }

    /**
     * 获取当前时间的后一天时间
     */
    private static String getAfterDay(Calendar cl) {
        //使用roll方法进行回滚到后一天的时间
        //cl.roll(Calendar.DATE, 1);
        //使用set方法直接设置时间值
        //int day = cl.get(Calendar.DATE);
        cl.add(Calendar.DATE, 1);
        return formatter.format(cl.getTime());
    }

    private static String getDateAMPM() {
        GregorianCalendar ca = new GregorianCalendar();
        //结果为“0”是上午     结果为“1”是下午
        int i = ca.get(GregorianCalendar.AM_PM);
        return i == 0 ? "AM" : "PM";
    }

    private static int compareToDate(String date1, String date2) {
        return date1.compareTo(date2);
    }

    private static int compareToDateString(String date1, String date2) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int i = 0;
        try {
            long ldate1 = formatter.parse(date1).getTime();
            long ldate2 = formatter.parse(date2).getTime();
            if (ldate1 > ldate2) {
                i = 1;
            } else if (ldate1 == ldate2) {
                i = 0;
            } else {
                i = -1;
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }
        return i;
    }

    public static String[] getFiveDate() {
        String[] dates = new String[2];
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        String five = " 05:00:00";

        if (getDateAMPM().equals("AM") && compareToDateString(getStringDate(), getStringDateShort() + five) == -1) {
            dates[0] = getBeforeDay(calendar) + five;
            dates[1] = getStringDateShort() + five;
        } else {
            dates[0] = getStringDateShort() + five;
            dates[1] = getAfterDay(calendar) + five;
        }

        return dates;
    }

    public static String getFiveDate2() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        String five = " 05:00:00";
        String reStr = "";
        if (getDateAMPM().equals("AM") && compareToDateString(getStringDate(), getStringDateShort() + five) == -1) {
            reStr = getBeforeDay(calendar);
        } else {
            reStr = getStringDateShort();
        }
        return reStr;
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate() {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static String getDate(int num) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, num);
        return DateFormatUtils.format(cal.getTime(), YYYY_MM_DD);
    }

    public static String getYYYYMMDate() {
        return dateTimeNow(YYYYMM);
    }

    public static String getTime() {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static String dateTimeNow() {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }

    public static String dateTime(final Date date) {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    public static Date dateTime(final String format, final String ts) {
        try {
            return new SimpleDateFormat(format).parse(ts);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static String datePath() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static String dateTime() {
        Date now = new Date();
        return DateFormatUtils.format(now, YYYYMMdd);
    }

    /**
     * 获取 此刻 到 第明天凌晨五点 剩余毫秒数
     */
    public static Long getTodayRemainingMillis(){
        String date = getPolicyEndDate(new Date());
        Long now = strToDateLong(date).getTime() - System.currentTimeMillis();
        now += (5 * 60 *60 * 1000);
        return now;
    }

    public static void main(String[] args) {



//        System.out.println(list.toString());

    }

}
